package com.zlm.design.flyweight;

import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * {@code 享元模式}
 *
 * @author zlm
 * @since 2025/6/24
 */
public class Main {

    public static void main(String[] args) throws Exception {
        BufferPool bufferPool = new BufferPool(1024, 256);
        ByteBuffer buffer = bufferPool.allocate(256, 1000);
        assert buffer != null;
        assert buffer.capacity() == 256;
        bufferPool.deallocate(buffer);
        ByteBuffer buffer1 = bufferPool.allocate(256, 1000);
        assert buffer == buffer1;

        System.out.println("=====================");
        testMultiThreadAllocationBlocking();
    }

    public static void testMultiThreadAllocationBlocking() throws Exception{
        BufferPool bufferPool = new BufferPool(512, 256);
        ByteBuffer b1 = bufferPool.allocate(256, 1000);
        ByteBuffer b2 = bufferPool.allocate(256, 1000);

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<ByteBuffer> future = executor.submit(() -> bufferPool.allocate(256, 10000));

        Thread.sleep(1000);

        System.out.println(future.isDone());

        bufferPool.deallocate(b1);
        ByteBuffer b3 = future.get(100, TimeUnit.MILLISECONDS);
        System.out.println(b3!= null);

        executor.shutdown();
    }
}
